package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/CatchZeng/dingtalk/pkg/dingtalk"
	"github.com/hpcloud/tail"
	"gopkg.in/yaml.v2"
)

var Host string

type ConfDingtalk struct {
	Access_token string `yaml:access_token`
	Secret       string `yaml:secret`
}

type ConfServices struct {
	Name     string `yaml:name`
	Regex    string `yaml:regex`
	Filepath string `yaml:filepath`
	Title    string `yaml:title`
	Interval int    `yaml:interval`
}

type Conf struct {
	Host     string `yaml:host`
	Dingtalk ConfDingtalk
	Services []ConfServices
}

func initYaml(confPath string) *Conf {
	var conf Conf
	cf, err := ioutil.ReadFile(confPath)
	if err != nil {
		fmt.Print(err)
	}
	yaml.Unmarshal(cf, &conf)
	return &conf
}

func tailf(cd *ConfDingtalk, cs *ConfServices) {
	var lock = true
	filepath := cs.Filepath
	tailFile, err := tail.TailFile(filepath, tail.Config{
		ReOpen:    true,
		Follow:    true,
		Location:  &tail.SeekInfo{Offset: 0, Whence: os.SEEK_END},
		MustExist: false,
		Poll:      true,
	})
	if err != nil {
		fmt.Println("tail file err:", err)
		return
	}

	for {
		msg, ok := <-tailFile.Lines
		if !ok {
			fmt.Printf("tail file close reopen,filename:%s\n", tailFile.Filename)
			time.Sleep(100 * time.Millisecond)
			continue
		}
		c := msg.Text
		r := regexp.MustCompile(cs.Regex)
		// fmt.Println(c)
		if r.MatchString(c) {
			if lock {
				go dingrobot(cd, cs, c, &lock)
			}
		}
	}
}

func dingrobot(cd *ConfDingtalk, cs *ConfServices, content string, lock *bool) {
	accessToken := cd.Access_token
	secret := cd.Secret
	title := cs.Title
	service := cs.Name
	*lock = false
	client := dingtalk.NewClient(accessToken, secret)
	markdownContent := fmt.Sprintf("### %s\n \n---\n- 告警服务：%s\n- 告警详情：  \n  %s\n- 告警时间：%s\n- 告警主机：%s",
		title, service, content, time.Now().Format("2006-01-02 15:04:05"), Host)
	msg := dingtalk.NewMarkdownMessage().SetMarkdown(title, markdownContent)
	client.Send(msg)
	// loginfo := "发送" + service + "钉钉告警, msg: " + content
	loginfo := fmt.Sprintf("发送[ %s ]钉钉告警 --> msg: [ %s ]", service, strings.TrimSpace(content))
	log.Println(loginfo)
	time.Sleep(time.Second * time.Duration(cs.Interval))
	*lock = true
}

func main() {
	wg := sync.WaitGroup{}
	confPath := flag.String("conf", "./conf.yaml", "tailf配置文件路径")
	flag.Parse()
	conf := initYaml(*confPath)
	Host = conf.Host
	cDingtalk := conf.Dingtalk
	for _, v := range conf.Services {
		wg.Add(1)
		cServices := v
		go tailf(&cDingtalk, &cServices)
	}
	wg.Wait()
}